

package com.seed.marketed.common.logtrack.intercept;

import java.util.Map;
import java.util.concurrent.Callable;

import com.seed.marketed.common.logtrack.constants.LogConstants;
import com.seed.marketed.common.utils.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;

import com.alibaba.ttl.TtlCallable;
import com.alibaba.ttl.TtlRunnable;




@Aspect
@Component
public class ThreadLogIntercept {
	
	@Pointcut("execution(public * java.util.concurrent.ThreadPoolExecutor.execute(..))") // 切入点表达式
	public void pointcut() {
	}
	
	@Before(value = "pointcut()")
	public void before(JoinPoint joinPoint) {
		
		//logger.info("===>拦截线程池,设置MDC");
		String traceId = MDC.get(LogConstants.TRACE_ID);
		if(StringUtils.isNotBlank(traceId)) {
			Map<String, String> context = MDC.getCopyOfContextMap();
			MDC.setContextMap(context);
		}

		 Object[] args = joinPoint.getArgs();
		   
		 for (Object object : args) {
			 	if(object instanceof Runnable) {
			 		 Runnable ttlRunnable = TtlRunnable.get((Runnable) object);
			 		 object = ttlRunnable;
			 	}else if(object instanceof Callable) {
			 		 Callable<?> ttlCallable = TtlCallable.get((Callable<?>) object);
			 		 object = ttlCallable;
			 	}
		 }
	}
	
	@Before(value = "@annotation(com.seed.marketed.common.logtrack.annotation.RunnableLogAnnotation)")
	public void runableBefore(JoinPoint joinPoint) {
		//logger.info("===>拦截新线程,设置MDC");
		Map<String, String> context = MDC.getCopyOfContextMap();
		if(context!= null) {
			MDC.setContextMap(context);
		}
	}
	
	@AfterReturning(value="@annotation(com.seed.marketed.common.logtrack.annotation.RunnableLogAnnotation)",returning="returnValue")
	public void runableAfterHandle(JoinPoint point,Object returnValue){
		MDC.remove(LogConstants.TRACE_ID);
	}
	
	 @AfterThrowing(value="@annotation(com.seed.marketed.common.logtrack.annotation.RunnableLogAnnotation)",throwing="e")
	public void runableAfterThrowable(JoinPoint joinPoint,Throwable e){
		MDC.remove(LogConstants.TRACE_ID);
	}
	
}
